#pragma once
#include "user_model.hpp"
#include <unordered_map>
#include <mutex>
#include <random>
#include <sstream>
#include "../../comm/log.hpp"

namespace ns_user_control
{
    using namespace ns_user_model;
    using namespace ns_log;

    class UserControl
    {
    private:
        UserModel user_model_;

        // Token管理 - 使用map存储token到user_id的映射
        // 实际生产环境中应该用Redis，这里为了简化使用内存map
        std::unordered_map<std::string, int> token_map_;   // token -> user_id
        std::unordered_map<int, std::string> user_tokens_; // user_id -> token
        std::mutex token_mutex_;//stl中的容器不是线程安全的

        // 生成随机Token - 简单的UUID式token:非标准UUID,借鉴其简单随机长字符串思想
        std::string GenerateToken()
        {
            static const char alphanum[] =
                "0123456789"
                "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                "abcdefghijklmnopqrstuvwxyz";

            std::random_device rd; 
            std::mt19937 gen(rd());
            std::uniform_int_distribution<> dis(0, sizeof(alphanum) - 2);

            std::stringstream ss;

            //token一共32位
            for (int i = 0; i < 32; i++)
            {
                ss << alphanum[dis(gen)];
            }
            return ss.str();
        }

    public:
        UserControl()
        {
            LOG(LogLevel::INFO)<< "UserControl initialized";
        }

        bool MapTokenToId(const std::string& token,int& user_id)
        {
            std::lock_guard<std::mutex> lock(token_mutex_);//需要加锁
            if(token_map_.count(token))
            {
                user_id = token_map_[token];
                return true;
            }
            else
                return false;
        }

        // 用户注册接口
        // 返回值：true-注册成功 false-注册失败
        // error_msg：失败时包含错误信息
        bool Register(const std::string &username,
                      const std::string &password,
                      const std::string &email,
                      std::string *error_msg)
        {
            // 1. 基本输入验证
            if (username.empty() || password.empty())
            {
                *error_msg = "用户名和密码不能为空";
                return false;
            }

            if (username.length() < 3 || username.length() > 20)
            {
                *error_msg = "用户名长度必须在3-20个字符之间";
                return false;
            }

            if (password.length() < 6)
            {
                *error_msg = "密码长度至少6个字符";
                return false;
            }

            // 2. 调用Model层注册用户
            if (!user_model_.RegisterUser(username, password, email))
            {
                *error_msg = "用户名已存在或数据库错误";
                LOG(LogLevel::INFO) << "Register failed: " << username;
                return false;
            }

            LOG(LogLevel::INFO) << "User registered: " << username;
            return true;
        }

        // 用户登录接口
        // 返回值：true-登录成功 false-登录失败
        // token：登录成功后返回的token，用于后续请求验证
        // error_msg：失败时包含错误信息
        bool Login(const std::string &username,
                   const std::string &password,
                   std::string *token,
                   User *user,
                   std::string *error_msg)
        {
            // 1. 验证用户名和密码
            if (!user_model_.VerifyUser(username, password, user))
            {
                *error_msg = "用户名或密码错误";
                LOG(LogLevel::WARNING) << "Login failed: " << username;
                return false;
            }

            // 2. 生成token并存储
            // RAII风格式锁管理
            std::lock_guard<std::mutex> lock(token_mutex_);

            // 如果用户已经登录，先删除旧token
            // 删除旧token,本质就是不允许同时存在多个登陆
            if (user_tokens_.count(user->user_id))
            {
                std::string old_token = user_tokens_[user->user_id];
                token_map_.erase(old_token);
            }

            // 生成新token
            // 存储好user_id->token,token->user_id的映射关系
            // 理论上存在token重复的概率,但非常小,但仍需处理(待处理)
            
            *token = GenerateToken();
            while(token_map_.count(*token))
                *token = GenerateToken();
            //此时,一定是不重复的token
            token_map_[*token] = user->user_id;
            user_tokens_[user->user_id] = *token;

            LOG(LogLevel::INFO) << "User logged in: " << username << ", token: " << *token;
            return true;
        }

        // 验证Token - 用于每次请求时验证用户身份
        // 返回值：true-token有效 false-token无效或过期
        bool ValidateToken(const std::string &token)
        {
            std::lock_guard<std::mutex> lock(token_mutex_);

            // 查找token对应的user_id
            auto it = token_map_.find(token);
            if (it == token_map_.end())
            {
                LOG(LogLevel::WARNING) << "Invalid token: " << token;
                return false;
            }

            // int user_id = it->second;

            // // 获取用户信息
            // if (!user_model_.GetUserById(user_id, user))
            // {
            //     LOG(LogLevel::ERROR) << "User not found for token: " << token;
            //     return false;
            // }

            return true;
        }

        // 用户登出
        // 将两个哈希表中的映射清除
        bool Logout(const std::string &token)
        {
            std::lock_guard<std::mutex> lock(token_mutex_);

            auto it = token_map_.find(token);
            if (it == token_map_.end())
            {
                return false;
            }

            int user_id = it->second;
            token_map_.erase(token);
            user_tokens_.erase(user_id);

            LOG(LogLevel::INFO) << "User logged out, token: " << token;
            return true;
        }

        // 获取用户信息
        bool GetUserProfile(int user_id, User *user)
        {
            return user_model_.GetUserById(user_id, user);
        }

        // 获取排行榜
        bool GetUserRanking(std::vector<User> &ranking, int limit = 100)
        {
            return user_model_.GetRanking(ranking, limit);
        }

        // 更新用户统计（在判题后调用）
        bool UpdateUserStats(int user_id, bool accepted)
        {
            return user_model_.UpdateUserStats(user_id, accepted);
        }

        // 获取用户提交历史
        bool GetUserSubmissions(int user_id, std::vector<Submission> &submissions)
        {
            return user_model_.GetUserSubmissions(user_id, submissions);
        }

        // 记录用户提交
        bool RecordSubmission(int user_id, const std::string &question_number, int status)
        {
            return user_model_.RecordSubmission(user_id, question_number, status);
        }
    };
}